用操纵符实现格式化输入输出,操纵符算子manipulator是一系列特殊的函数,它不属于任何类的成员,主要用来格式化输入输出,定义在iostream.h和iomanip.h两个头文件中。endl插入一个新行并刷新流;flush刷新流;
cout<<"你的出生年月是:"<<birth<<endl;
1 文本:""2 变量:直接的变量名;3 换行:endl
字符数据char s[25];
cout<<"请输入字符串:\n";
cin.getline(s,25);
cout<<s<<"\n";
#include "iostream";
string s1="张三";
cout<<s1.c_str()<<endl;
C或C++的控制台程序的输入函数,空格或回车都表示一个值输入的结束;
在C++中,setw(int n)用来控制输出间隔。
cin(发音为 see-in):读入标准输入的 istream 对象。
包含其的库事先从类istream实例化的一个对象,该类有重载>>,且因为其返回值也是istream对象,所以可以被链式使用,同样的cout也是如此。
endl 操纵符,用于输出一个换行符并刷新缓冲区。除此之外,C++ 语言还提供了另外两个类似的操纵符。第一个经常使用的 flush,用于刷新流,但不在输出中添加任何字符。第二个则是比较少用的 ends,这个操纵符在缓冲区中插入空字符 null,然后后刷新它:
用C++读写文件
#include<iostream> #include<fstream> using namespace std; int main() { fstream file("test.txt",ios::out); if(!file.fail()) { cout<<"star write"<<endl; file<<"1 name:"<<"\r\n"; file<<"2 sex:"<<endl; cout<<"successfully writed!"<<endl; } else cout<<"can not open"<<endl; file.close(); system("pause"); return 0; }
// reading a text file #include<iostream.h> #include<fstream.h> #include<stdlib.h> int main () { char buffer[256]; ifstream in("test.txt"); if (! in.is_open()) { cout << "Error opening file"; exit (1); } while (!in.eof() ) { in.getline (buffer,100); cout << buffer << endl; } system("pause"); return 0; }
endl表示输入一个换行符,同时刷新流。
输出a的16进制:cout<<hex<<a<<endl;
cout<<a;
cout是对象,<<是操作符,a是操作数。
cin对象的默认输入设备是键盘;cout对象的默认输出设备是屏幕;
不同数据类型的输入和输出是对插入操作符和抽取操作符的重载。
操作后的返回结果仍然是输入输出流的对象,便于连续输入或输出。
在C++中有ifstream和ofstream类,它们的默认输入/输出设备都是磁盘文件。
cin以空格作为字符串的结束依据,不会被读入;
成员函数getline可以将空格一起读入;
istream& getline(char *, int, char = '\n');
第一个参数用于指定字符数组的首地址;
第二个参数用于指定允许诗篇的最多字符个数;
第三个参数用于指定表示输入结束的字符,默认为回车;
C++语言本身是不提供输入输出操作的,它的输入/输出(input/output)由标准库提供。标准库定义了一组类型,支持对文件和控制窗口等设备的读写(IO)。还定义了其他一些类型,使string 对象能够像文件一样操作,从而使编程者无须IO 就能实现数据与字符之间的转换。这些IO 类型都定义了如何读写内置数据类型的值。此外,类的设计者还可以很方便地使用IO 标准库设施读写自定义类的对象。类类型通常使用IO 标准库为内置类型定义的操作符和规则来进行读写。
输入输出作为库载入,也是为了空间效率的考量,当你不需要时,就可以不载入,让程序更轻量级。
标准库的输入输出功能就涉及了流的使用。C++的输入输出流是指由若干字节组成的字节序列,这些字节中的数据按顺序从一个对象传送到另一个对象。流实际上是程序中输入或者输出设备的一种抽象表示,它表示了信息从源端到目的端的运动。在输入操作时, 字节流从输入设备(如键盘、磁盘)流向内存;在输出操作时,字节流从内存流向输出设备(例如屏幕、打印机、磁盘等)。流中的内容可以是ASCII 字符、二进制形式的数据、图形图像、数字音频视频或其他形式的信息。
实际上,在内存中为每个数据流开辟一个内存缓冲区,是用来存放流中的数据。流是与内存缓冲区相对应的,或者可以说,缓冲区中的数据就是流。
C++有哪4个预定义的流?
C++预定义了四个流对象:cin、cout、cerr和clog,分别对应于标准输入流、标准输出流、无缓冲的标准错误流以及有缓冲的标准错误流。
什么时候用输入方式打开文件?什么时候应该用输出方式打开文件?什么时候该用app方式打开文件?
程序需要从文件读取信息时,以输入方式打开。如果需要把程序中的某些信息写到文件中去,以输出方式打开文件。当以输出方式打开某个文件时,文件中原有的内容会被清除。如果想保留文件中原有的内容,将新加入的内容添加在原内容后面,可以用app方式打开。
哪些流操纵符只对下一次输入/输出有效?哪些流操纵符是一直有效直到被改变?
常用的流操纵符中,setw和setFill只对下一次输入输出有效。设置整型数的基数和设置浮点数的精度是一直有效,直到被改变为止。
各编写一条语句完成下列功能:
a.使用流操纵符输出整数100的八进制、十进制和十六进制的表示。
b.以科学计数法显示实型数123.4567。
c.将整型数a输出到一个宽度为6的区域,空余部分用’$’填空。
d.输出char *类型的变量ptr中保存的地址。
a、 cout << oct << 100 << ‘\t’ << dec << 100 << ‘\t’ << hex << 100 << endl;
b、 cout << scientific << 123.456 << endl;
c、 cout << setw(6) << setfill(‘$’) << a << endl ;
d、 cout << (void *)ptr << endl;
printf()、scanf()不能“智能”地处理类型,这个任务交给程序员去完成。同时,也无法直接用预定义的库函数来完成类类型的输入输出。这使得程序员不得不用更多的代码来完成新类型数据的输入输出。作为比C更好的语言,C++当然会提出解决问题的方式,这就是流(Stream)。
C++采用继承的方法建立了比较实用的流库。
输入输出流被定义为类,C++的I/O库中的类称为流类,用流类定义的对象称不流对象,例如,cin是输入流对象,cout是输出流对象。
C++流库中的所有流、对象和函数都定义在标准名字空间std中,因此,使用I/O流需要用到以下名字限定语法。
std::cout
输入是数据从输入设备(如键盘、磁盘和鼠标等)到内存的过程,输出是内存中的数据输出到输出设备(如显示屏幕、打印机和磁盘等)的过程。输入输出过程中,数据像流水一样从一处流到另外一处,C++形象地描述该过程为流。流的内容可以是ASCII码字符、二进制形式的数据、图形图像、数字音频视频或者其他形式的信息。
当开始执行C++程序时,C++会有几个自动打开的预定义流,分别是:cin(相当于C的stdin)、cout(相当于C的stdout)、cerr和clog(相当于C的stderr)。
cerr没有被缓冲,而clog有被缓冲。
默认情况下,C++标准流cin和cout被连到控制台上,但它也可以被重新定向。cerr和clog与标准错误设备相关连,它不能被重新定向,因此,输出到cerr和clog的信息总是能在屏幕上显示。
istream流类将运算符>>重载为输入运算符。
istream和ostream两个类提供了流库的主要输入输出界面。
输出运算符<<也称为插入(Inserting)运算符,通过输出运算符传送到输出设备。输出运算符有两个操作数,左操作数为ostream类类型的对象,右操作数是存储输出数据的变量,可以是一个预定义类型的变量,也可以是重载了该运算符(<<)的类的对象。输出运算符采用左结合方式,允许多个输出操作组合到一个语句中。
输入出运算符>>也称为提取(Extraction)运算符,通过输入运算符传送到输入设备。输入运算符有两个操作数,左操作数为istream类类型的对象,右操作数是存储输出数据的变量,可以是一个预定义类型的变量,也可以是重载了该运算符(>>)的类的对象。输出运算符采用左结合方式,允许多个输出操作组合到一个语句中。
在默认情况下,运算符>>跳过空白符,然后读入对应于输入变量类型的值。对于类型char*(作为串看待),运算符>>的作用也是跳过空白,读入以下非空白字符,直到发现另一个空白字符为止,并在串尾放一个字符'\0',要小心避免串溢出。
重载运算符函数operator>>的第二个参数必须是一个引用。
在C++中,要进行文件I/O,首先必须创建一个流,然后将这个流与文件相关联(称为打开文件),这时才能进行读写操作。使用完后,需要关闭文件。
ofstream ofile("test.txt");
ofstream类自动打开文件的构造函数,该构造函数的参数和默认值与open()函数相同。
可用文件保存程序输入或接收程序输出。用于程序I/O 的“文件”和用于保存程序的“文件”没有区别。利用“流”,程序可以采用统一的方式处理文件输入与键盘输入,并可采用统一的方式处理文件输出与屏幕输出。
流(stream)是由字符(或其他类型的数据)构成的“流”(flow)。流向程序,称为输入流(inputstream)。流出程序,则称为输出流(output stream)。如输入流来自键盘,表明程序要从键盘获取输入。如输入流来自文件,表明程序要从文件获取输入。类似地,输出流可发送给屏幕或文件
可将流连接到的文件视为这个流的值。可以将流与文件断开,再连接到另一个文件,换言之,可以更改流变量的值。然而,必须使用专门处理流的函数才能完成这些更改。不能像使用int 或char 类型的变量那样在赋值语句中使用流变量。虽然流是变量,但它们是特殊的变量。
cin 和cout 流是系统已经为你声明好的。要将流连接到文件,必须像声明其他任何变量那样声明流。“输入文件流”(input-file stream)变量的类型名称是ifstream;“输出文件流”(output-file stream)变量的类型名称是ofstream。所以,要将inStream 声明为用于文件的输入流,将outStream 声明为用于另一个文件的输出流,需要使用如下所示的语句:
ifstream inStream;
ofstream outStream;
流变量(例如前面声明的inStream 和outStream)必须连接到一个文件。这称为打开文件,用open 函数完成该操作。例如,假定希望输入流inStream 连接到infile.dat 文件,程序首先执行以下语句,然后才能从该文件读取输入:
inStream.open("infile.dat");
程序使用的每个输入和输出文件都有两个名称。外部文件名是文件真实名称,但只在open函数调用中使用一次,该函数将文件连接到一个流。一旦调用了open,就必须将流名称作为文件名使用。
程序完成从文件输入或者向文件输出之后,应该将文件关闭。关闭文件导致流与文件断开。调用close 函数关闭文件。:inStream.close();
如程序正常终止,但没有关闭文件,系统会自动为你关闭。但最好养成主动关闭文件的好习惯,原因有二。
其一,只有在程序正常终止的前提下,系统才会为你关闭文件。假如程序因为错误而异常终止,文件就不会关闭,并可能损坏。程序在结束文件处理后立即关闭文件,文件损坏的几率就大大降低。
其二,你可能希望程序将输出发送给一个文件,以后又将那些输出读回程序。为此,程序应该在完成向文件的写入之后立即关闭文件,再用open 函数将文件连接到一个输入流(也可以打开一个文件,并同时进行输入和输出,但方式稍有区别)。
操作符>>和<<可像应用于cin 和cout 那样应用于连接到文件的流。但文件I/O 的编程风格有别于屏幕和键盘I/O。(读取键盘输入应提示并回显用户输入)
可同时打开多个流进行输入输出。因此,一个程序可以既从键盘获取输入,也从一个或多个文件获取输入。同一个程序可以既向屏幕发送输出,也向一个或多个文件发送输出。另外,还可从键盘获取所有输入,并将输出同时发送到屏幕和文件。输入流和输出流可任意组合。
流可作为函数实参使用。唯一限制就是形参必须传引用。
每个输入文件流都有名为eof 的成员函数,用于判断何时读完文件的全部内容,没有更多的输入。
ifstream 类型的流可通过调用成员函数open 连接到文件。之后就可从文件读取输入。
ofstream 类型的流可通过调用成员函数open 连接到文件。之后就可将输出发送到文件。
应使用成员函数fail 检查open 函数调用是否成功。
对象是关联了函数的变量。这些函数称为成员函数。类是其变量为对象的一种类型。例如,一个流是一个对象,而ifstream 和ofstream 是类。
流的一些成员函数(比如width,setf 和precision)可用于格式化输出。这些输出函数同时适用于连接到屏幕的cout 流和连接到文件的输出流。
每个输入流都有名为get 的成员函数,用于读取一个字符输入。get 不会忽略空白字符。每个输出流都有名为put 的成员函数,用于将一个字符写到输出流。
成员函数eof 测试是否抵达输入文件末尾。eof 适合文本处理。
函数可以有流类型的形参,但参数只能传引用而不能传值。
将istream(没有f)用作输入流参数的类型,与该参数对应的实参既可以是cin流,也可以是ifstream(有f)类型的输入文件流。将ostream(没有f)用作输出流参数的类型,与该参数对应的实参既可以是cout 流,也可以是ofstream(有f)类型的输出文件流。
文件和程序变量都可存储值,而且都可从中检索(获取)值。程序变量只存在于程序运行期间,而文件在程序运行前就可能存在,而且在程序终止之后可继续存在。简单地说,文件可以是永久性的,变量则不然。文件能存储大量数据,变量则不能提供如此大的存储量。
文件:如直接处理而不需显示的数据一般以二进制形式存储,字符串显示数据通常以文本形式存储。
如何对文件进行读写操作:实例化一个流对象,利用流对象方法open打开一个文件(参数是路径+打开方式),这样就可以对文件进行读写了。如果某些文件因为某些原因不能打开(如欲写文件的磁盘已满,或想写到U盘,但U盘沿未插好等),流对象的值为0.在对文件进行操作前,必须确保文件已打开,否则 要进行相应的处理。为确认打开文件是否成功,通常固定采用好下程序段。
ifstream ex4("test.txt"); if(!ex4) { cout<"Can't open the file!\n"; exit(1); //标准库函数,在stdlib.h中,程序结束,并返回1作为错误代码 }
用cin输入时是以空格、回车或Tab键作为结束符。因此无法输入包含空白字符的字符串
在用cin输入时,要注意输入的字符串的长度不能超过数组的长度。因此,最好在输出的提示信息中告知允许的最长字符串长度。
文件操作:建立流(C的流指针与C++的流对象),让一个文件与之相关联,如C的open函数,c++的open方法或直接初始化时附加一个路径。建立关联也称为打开文件,取消关联也称为关闭文件;
In <fstream>, the standard library provides streams to and from a file:
ifstreams for reading from a file
ofstreams for writing to a file
fstreams for reading from and writing to a file
ofstream ofs {"target"}; // "o" for "output"
if (!ofs)
error("couldn't open 'target' for writing");
Testing that a file stream has been properly opened is usually done by checking its state.
ifstream ifs {"source"}; // "i" for "input"
if (!ifs)
error("couldn't open 'source' for reading");
Assuming that the tests succeeded, ofs can be used as an ordinary ostream (just like cout) and ifs can be used as an ordinary istream (just like cin).
Use cout for normal output and cerr for errors;
ofstream(fileName, mode)
ios::app : start writing at end of file
ios::ate: start reading or writing at end of file
Ios::in : open for reading
ios::trunc: truncate file to zero length if it exists
ios::nocreate : error when opening if file does not exist
ios::noreplace: error when opening for output if file exists.
ios::binary: open file in binary mode.
ios::out : open for writing
fstream file; file.open("Group.dat", ios::app | ios:: out | ios::in | ios::binary);
基类ios(继承istream的类)提供一个重载的强制类型转换运算符,将流变成void*类型的指针。如果读取数值时发生错误或遇到文件结束符,则指针值为0。编译器能够隐式使用void*类型的强制转换运算符。
stringstream类用于执行C++风格的串流的输入操作。
ostringstream类用于执行C风格的串流的输出操作。
strstream类同时可以支持C风格的串流的输入输出操作。
C++语言把每一个文件都看成一个有序的字节流(把文件看成n个字节)
每一个文件以文件结束符(end-of-file marker)结束。
当打开一个文件时,该文件就和某个流关联起来。
与这些对象相关联的流提供程序与特定文件或设备之间的通信通道。
例如.cin对象(标准输入流对象)使程序能从键盘输入数据,cout对象(标准输出流对象)使程序能向屏幕输出数据。
C++文件的读写和控制台读写一样,可以用流提取运算符“>>”从文件读数据,也可以用流插入运算符”<<”将数据写入文件,也可以用文件流的其他成员函数读写文件,如get函数,put函数等。
判断文件结束
>>读:可以通过判断输入流对象值是否为0。
get读:判断读入字符是否是EOF。
其他方式读:通过成员函数eof。eof函数不需要参数,返回一个整型值。当读操作遇到文件结束时,该函数返回1,否则返回0。
cout流通常是传送到显示器输出,但也可以被重定向输出到磁盘文件,而cerr流中的信息只能在显示器输出。
由于文件设备并不像显示器屏幕与键盘那样是标准默认设备,所以它在fstream.h头文件中是没有像cout那样预先定义的全局对象,所以我们必须自己定义一个该类的对象。
ostrstream::str()返回的是char*
ostringstream::str()返回的是std::string
缓冲的流:不是立即将数据发送到目的地,而是缓冲输入的数据,然后以块的方式发送。
流不仅包含普通数据,还包含称为当前位置(current position)的特殊数据。当前位置指的是流将要进入下一次读写操作的位置。
流的三个公共的来源或目的地:控制台、文件和字符串;
流内建了标记化的功能。
cin
#include <string> #include <iostream> int main() { std::cout << "Pick 1 or 2: "; int choice=0; std::cin >> choice; // cin actually gets the string "1\n" or "2\n". // It then extracts the 2 to variable choice, // leaving the newline stuck in the input stream. //std::cin.ignore(32767, '\n'); // ignore up to 32767 characters until a \n is removed std::cout << "Now enter your name: "; std::string name=""; std::getline(std::cin, name); // name only get '\n' std::cout << "Hello, " << name << ", you picked " << choice << '\n'; system("pause"); return 0; }
Some devices, such as files and networks, are capable of being both input and output sources.
cin.ignore(32767, '\n'); // clear out any additional input from the stream
One interesting note is that std::endl; also flushes the output stream. Consequently, overuse of std::endl (causing unnecessary buffer flushes) can have performance impacts when doing buffered I/O where flushes are expensive (such as writing to a file). For this reason, performance conscious programmers will often use ‘\n’ instead of std::endl to insert a newline into the output stream, to avoid unnecessary flushing of the buffer.
流(Streams)
只在记录日志时使用流。
定义:流是printf()和scanf()的替代。
优点:有了流,在输出时不需要关心对象的类型,不用担心格式化字符串与参数列表不匹配(虽然在gcc中使用printf也不存在这个问题),打开、关闭对应文件时,流可以自动构造、析构。
缺点:流使得pread()等功能函数很难执行,如果不使用printf之类的函数而是使用流很难对格式进行操作(尤其是常用的格式字符串%.*s),流不支持字符串操作符重新定序(%1s),而这一点对国际化很有用。
结论:
不要使用流,除非是日志接口需要,使用printf之类的代替。
使用流还有很多利弊,代码一致性胜过一切,不要在代码中使用流。
std::cin.clear(); // reset any error flags
std::cin.ignore(std::numeric_limits
std::cin.get(); // get one more char from the user
串流类是ios中的派生类
C++的串流对象可以连接string对象或字符串
串流提取数据时对字符串按变量类型解释;插入数据时把类型数据转换成字符串
串流I/O具有格式化功能
二进制文件以基本类型数据在内存的二进制表示形式存放。
数据,不对写入或读出的数据做格式转换二进制文件的读写方式由程序控制。
打开二进制文件用binary方式。
二进制文件是随机存取文件。
字符流机制的核心思想:与字符串流关联的字符数组相当于内存中的临时ASCII文件,可以以ASCII形式存入各种类型的数据。对它读写数据的用法相当于标准设备(显示器与键盘),但标准设备不能保存数据,字符串流可以暂时保存数据。另外,字符串流比磁盘文件使用方便,不必建立文件(不需要打开和关闭),存取速度快。其缺点是生命周期与其所在的模块(如主函数)相同,结束结束了,字符数组与不存在了。
A stream acts as an intermediary between the program and the stream’s source or destination. This approach enables a C++ program to treat input from a keyboard in the same manner it treats input from a file;
the C++ program merely examines the stream of bytes without needing to know where the bytes come from. Similarly, by using streams, a C++ program can process output in a manner independent of where the bytes are going.
ignore()提取并舍弃不用。
unget()重新放回流中。